#include "Dog.h"
#include<string>
#include<iostream>
#include<fstream>

//data members
//       string sex;
//       string name;
//       string dna;


//constructors
Dog::Dog()
{
   //default constructor

}

Dog::Dog(string Sex, string Name, string Dna)throw (AppError)
{
   //parametric constructor

   if(Sex!= "male" && Sex!= "female") throw AppError("invalid sex", "Dog::Dog");
   if(Dna!= "dog") throw AppError("invalid dna", "Dog::Dog");
   Pet::name = Name;
   Pet::sex = Sex;
   Pet::dna = Dna;

}

void Dog::Perform(string cmd, ostream& fout)throw (AppError)
{
    if(cmd == "name?")
    {
         fout << "My name is " << Pet::MyNameIs();
    }
    else if(cmd == "species?")
    {
         fout << "My species is " << Pet::MySpeciesIs();
    }
    else if(cmd == "sex?")
    {
         fout << "My sex is " << Pet::MySexIs();
    }
    else if(cmd == "speak!")
    {
         fout << "My bark is " << Dog::Bark();
    }
    else throw AppError("Invalid command", "Dog::Perform");
}

void Dog::Perform(string cmd, ostream& fout, Dog& B) throw (AppError)
{
     //Method that only includes the case when comand = Mate!
     if(cmd == "mate!")
    {
         fout << "The offspring is: ";
         Dog::Mate(B).Insert(fout);
    }
    else throw AppError("Invalid command", "Dog::Perform");
}

void Dog::Extract(ifstream& istr)throw (TokenError)
{
    //fin = istr;
    string opentkn, closetkn;
    istr >> opentkn;
    if(opentkn!= "Dog{")
    {
         throw TokenError("Invalid Open Token!", "Dog::Extract(1)");
    }
    Get(istr);
    istr >> closetkn;
    if(closetkn!= "}Dog")
    {
         throw TokenError("Invalid Close Token!", "Dog::Extract(2)");
    }
}

void Dog::Insert(ostream& ostr)
{
    ostr << "Dog{ " ;
    Put(ostr);
    ostr << " }Dog ";
}

string Dog::Bark()
{
    if(sex == "male")return "Woof";
    else
         return "Woof Woof";
}

Dog Dog::Mate(Dog B) throw (AppError)
{
    //if(B.dna!= "dog")throw AppError("invalid dna", "Dog class, Mate method");       //if is not Dog throw error
    if(B.Pet::sex == Pet::sex)throw AppError("invalid sex", "Dog class, Mate method");       //if same sex throw error
    else
     {
        Dog C = Dog::Dog(Pet::sex, Pet::name + "+" + B.Pet::name, Pet::dna);
        return C;
     }
}

void Dog::Get(ifstream& fin) throw (TokenError)
{
   string reader;
   fin  >> reader;
   if( reader != "name:" )
	   throw TokenError("Invalid field label, name: expected", "Dog::Get(1)");
   fin  >> name;
   fin  >> reader;
   if( reader != "dna:" )
	   throw TokenError("Invalid field label, dna: expected", "Dog::Get(2)");
   fin  >> dna;
   fin  >> reader;
   if( reader != "sex:" )
	   throw TokenError("Invalid field label, sex: expected", "Dog::Get(3)");
   fin  >> sex;

}

void Dog::Put(ostream& fout) throw (TokenError)
{

   fout << " name: "  << Pet::name
        << " dna: "   << Pet::dna
        << " sex: "   << Pet::sex;

}

//string Dog::MyNameIs()
//{
//    return name;
//}
//
//string Dog::MySpeciesIs()
//{
//    return dna;
//}
//
//string Dog::MySexIs()
//{
//    return sex;
//}



